package com.ruoyi.asms.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.ruoyi.ams.controller.AmsAssetTypeController;
import com.ruoyi.ams.controller.AmsOwnAddressController;
import com.ruoyi.asms.domain.*;
import com.ruoyi.asms.domain.dto.WorkOrderDto;
;
import com.ruoyi.asms.domain.vo.*;
import com.ruoyi.asms.service.*;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsAssetType;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.security.service.TokensService;
import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 故障资产设备信息Controller
 *
 * @author yfkj
 * @date 2021-10-21
 */
@RestController
@RequestMapping("/asms/AsmsFaultAsset")
public class AsmsFaultAssetController extends BaseController {
    @Autowired
    private IAsmsFaultAssetService asmsFaultAssetService;
    @Autowired
    private IAsmsFaultService asmsFaultService;
    @Autowired
    private IFaultInfoViewService faultInfoViewService;
    @Autowired
    private IAsmsFaultReportStageService asmsFaultReportStageService;
    @Autowired
    private IAsmsFaultDispatchStageService asmsFaultDispatchStageService;
    @Autowired
    private IAsmsFaultConfirmStageService asmsFaultConfirmStageService;
    @Autowired
    private IAsmsFaultFeedbackStageService asmsFaultFeedbackStageService;
    @Autowired
    private IAsmsFaultAssetReasonService asmsFaultAssetReasonService;
    @Autowired
    private IAsmsMaintenanceChargeInfoService asmsMaintenanceChargeInfoService;
    @Autowired
    private IAsmsMaintenanceAssetService asmsMaintenanceAssetService;
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
    @Autowired
    private IAsmsFaultResolveStageService asmsFaultResolveStageService;
    @Autowired
    private IAsmsOwnChargeInfoService asmsOwnChargeInfoService;
    @Autowired
    private TokensService tokenService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteAssetAddressService remoteAssetAddressService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteFileService remoteFileService;
//    @Autowired
//    private RemoteAssetTypeService remoteAssetTypeService;
    @Autowired
    private AsyncService asyncService;
    @Autowired
    private AsmsReusingService asmsReusingService;
    @Autowired
    private IAsmsOwnMaintenanceDeptService maintenanceDeptService;
    @Autowired
    private AmsAssetTypeController assetTypeController;
    @Autowired
    private SysDeptController deptController;
    @Autowired
    private SysUserController userController;
    @Autowired
    private AmsOwnAddressController ownAddressController;

    /**
     * 查询
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:list")
    @GetMapping("/list")
    public TableDataInfo list(AsmsFaultAsset asmsFaultAsset) {
        startPage();
        List<AsmsFaultAsset> list = asmsFaultAssetService.selectAsmsFaultAssetList(asmsFaultAsset);
        return getDataTable(list);
    }

    /**
     * 导出故障资产设备信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:export")
    @Log(title = "故障资产设备信息", businessType = BusinessType.EXPORT)
    @PostMapping(value="/export", produces = "application/octet-stream")
    public void export(HttpServletResponse response, AsmsFaultAsset asmsFaultAsset) throws IOException {
        List<AsmsFaultAsset> list = asmsFaultAssetService.selectAsmsFaultAssetList(asmsFaultAsset);
        ExcelUtil<AsmsFaultAsset> util = new ExcelUtil<AsmsFaultAsset>(AsmsFaultAsset.class);
        util.exportExcel(response, list, "故障资产设备信息数据");
    }

    /**
     * 获取故障资产设备信息详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:query")
    @GetMapping(value = "/{faultAssetId}")
    public AjaxResult getInfo(@PathVariable("faultAssetId") Long faultAssetId) {
        return AjaxResult.success(asmsFaultAssetService.selectAsmsFaultAssetByFaultAssetId(faultAssetId));
    }

    /**
     * 新增故障资产设备信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:add")
    @Log(title = "故障资产设备信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AsmsFaultAsset asmsFaultAsset) {
        return toAjax(asmsFaultAssetService.insertAsmsFaultAsset(asmsFaultAsset));
    }

    /**
     * 修改故障资产设备信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:edit")
    @Log(title = "故障资产设备信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AsmsFaultAsset asmsFaultAsset) {
        return toAjax(asmsFaultAssetService.updateAsmsFaultAsset(asmsFaultAsset));
    }

    /**
     * 删除故障资产设备信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "asms:AsmsFaultAsset:remove")
    @Log(title = "故障资产设备信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{faultAssetIds}")
    public AjaxResult remove(@PathVariable Long[] faultAssetIds) {
        return toAjax(asmsFaultAssetService.deleteAsmsFaultAssetByFaultAssetIds(faultAssetIds));
    }

    /**
     * 分资产类型故障数量统计
     */
    @GetMapping("/getFaultNumberByAssetType")
    public AjaxResult getFaultNumberByAssetType() {
        QueryWrapper<AsmsFaultAsset> queryWrapper = new QueryWrapper<>();
        if (SecurityUtils.getUserId() != 1L) {
            Set<Long> userMaintenanceDeptIds = tokenService.getUserMaintenanceDeptIds();
            if (userMaintenanceDeptIds == null || userMaintenanceDeptIds.size() == 0) {
                return AjaxResult.success(new ArrayList<>());
            } else {
                queryWrapper.in(AsmsFaultAsset.MAINTENANCE_DEPT_ID, userMaintenanceDeptIds);
            }
        }
        queryWrapper.select(AsmsFaultAsset.ASSET_TYPE_ID, AsmsFaultAsset.ASSET_TYPE_ANCESTORS);
        List<AsmsFaultAsset> list = asmsFaultAssetService.list(queryWrapper);
        if (list.size() == 0) {
            return AjaxResult.success(new ArrayList<>());
        }
        R<List<TreeSelect>> rTypeTreeList = assetTypeController.rTreeselect();
        List<TreeSelect> typeTreeList = rTypeTreeList.getData();
        getTypeFaultStatistic(list,typeTreeList);
        return AjaxResult.success(typeTreeList);
    }

    /**
     * 分资产类型故障数量统计
     */
    @GetMapping("/getAllFaultsTask")
    public R<AllFaultsTaskVo> getAllFaultsTask(@RequestParam("startTime")Long startTime) {
        QueryWrapper<AsmsFaultAsset> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(AsmsFaultAsset.FAULT_ASSET_ID, AsmsFaultAsset.MAINTENANCE_DEPT_ID, AsmsFaultAsset.OWN_DEPT_ID, AsmsFaultAsset.ASSET_TYPE_ID, AsmsFaultAsset.ASSET_TYPE_ANCESTORS);
        queryWrapper.gt(AsmsFaultAsset.CREATE_TIME,startTime);
        List<AsmsFaultAsset> list = asmsFaultAssetService.list(queryWrapper);
        R<List<TreeSelect>> rTypeTreeList = assetTypeController.treeselectExclel();
        List<TreeSelect> typeTreeList = rTypeTreeList.getData();
        Map<Long,List<FaultFullInfoExcel>> mDeptIdFaultMap = new HashMap<>();
        Map<Long,List<FaultFullInfoExcel>> oDeptIdFaultMap = new HashMap<>();
        for (AsmsFaultAsset faultAsset : list) {
            FaultFullInfoVo faultFullInfo = asmsReusingService.getFaultFullInfo(faultAsset.getFaultAssetId());
            FaultFullInfoExcel excelVo = new FaultFullInfoExcel();
            BeanUtils.copyProperties(faultFullInfo.getBasicInfo(),excelVo);
            excelVo.setCreateTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z,faultFullInfo.getBasicInfo().getCreateTime()));
            if(faultFullInfo.getConfirmStage()!=null){
                BeanUtils.copyProperties(faultFullInfo.getConfirmStage(),excelVo);
                excelVo.setConfirmStageStartTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z,faultFullInfo.getConfirmStage().getStartTime()));
                excelVo.setConfirmStageEndTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z,faultFullInfo.getConfirmStage().getEndTime()));
                // -1超时未确认支付，0正在确认或支付中，1已确认或支付，2超时自动确认
                String confiremMsg ="";
                if(faultFullInfo.getConfirmStage().getStatus()!=null){
                    switch (faultFullInfo.getConfirmStage().getStatus()){
                        case -1:confiremMsg="超时未确认支付";
                        case 0:confiremMsg="正在确认或支付中";
                        case 1:confiremMsg="已确认或支付";
                        case 2:confiremMsg="超时自动确认";

                    }

                }
                excelVo.setConfirmStageStatusStr(confiremMsg);
            }
            if(faultFullInfo.getDispatchStage()!=null) {
                BeanUtils.copyProperties(faultFullInfo.getDispatchStage(), excelVo);
                excelVo.setDispatchStartTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getDispatchStage().getStartTime()));
                excelVo.setDispatchEndTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getDispatchStage().getEndTime()));

                if(faultFullInfo.getDispatchStage().getStatus()!=null){
                    excelVo.setDispatchStatusStr(faultFullInfo.getDispatchStage().getStatus() == 0 ? "正在处理中" : "处理结束");
                }
            }
            if(faultFullInfo.getReportStage()!=null) {
                BeanUtils.copyProperties(faultFullInfo.getReportStage(), excelVo);
                excelVo.setReportStartTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getReportStage().getStartTime()));
                excelVo.setReportEndTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getReportStage().getEndTime()));
                //-1不允许报修，0正在报修申请中，1允许报修，2客户已自行解决
                String reportMsg = "";
                if(faultFullInfo.getReportStage().getStatus()!=null){
                    switch (faultFullInfo.getReportStage().getStatus()) {
                        case -1:
                            reportMsg = "不允许报修";
                        case 0:
                            reportMsg = "正在报修申请中";
                        case 1:
                            reportMsg = "允许报修";
                        case 2:
                            reportMsg = "客户已自行解决";
                    }
                }

                excelVo.setReportStatusStr(reportMsg);
            }
            if(faultFullInfo.getResolveStage()!=null) {
                BeanUtils.copyProperties(faultFullInfo.getResolveStage(), excelVo);
                excelVo.setResolveStartTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getResolveStage().getStartTime()));
                excelVo.setResolveEndTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultFullInfo.getResolveStage().getEndTime()));

                if(faultFullInfo.getResolveStage().getStatus()!=null){
                    excelVo.setResolveStatusStr(faultFullInfo.getResolveStage().getStatus() == 0 ? "正在处理中" : "处理结束");
                }
                //1现场解决、2远程解决 //(1硬件、2软件、3其他)
                if((faultFullInfo.getResolveStage().getResolveType()!=null)){
                    excelVo.setResolveTypeStr(faultFullInfo.getResolveStage().getResolveType() == 1 ? "现场解决" : "远程解决");
                }else {
                    excelVo.setResolveTypeStr("其他");
                }

                String faultTypeMsg = "";
                if(faultFullInfo.getResolveStage().getFaultType()!=null){
                    switch (faultFullInfo.getResolveStage().getFaultType()) {

                        case 1:
                            faultTypeMsg = "硬件";
                        case 2:
                            faultTypeMsg = "软件";
                        case 3:
                            faultTypeMsg = "其他";
                    }
                    excelVo.setFaultTypeStr(faultTypeMsg);
                }else {
                    excelVo.setFaultTypeStr("其他");

                }

            }
            mDeptIdFaultMap.merge(faultAsset.getMaintenanceDeptId(), Lists.newArrayList(excelVo),(o,n)->{
                o.addAll(n);
                return o;
            });
            oDeptIdFaultMap.merge(faultAsset.getOwnDeptId(), Lists.newArrayList(excelVo),(o,n)->{
                o.addAll(n);
                return o;
            });
        }
        Map<Long,List<TreeSelect>> mDeptIdFaultStatisticMap= getTypeTreeStatistic(mDeptIdFaultMap,typeTreeList);
        Map<Long,List<TreeSelect>> oDeptIdFaultStatisticMap= getTypeTreeStatistic(oDeptIdFaultMap,typeTreeList);
        AllFaultsTaskVo vo =new AllFaultsTaskVo();
        vo.setMDeptIdFaultMap(mDeptIdFaultMap);
        vo.setMStatistic(mDeptIdFaultStatisticMap);
        vo.setODeptIdFaultMap(oDeptIdFaultMap);
        vo.setOStatistic(oDeptIdFaultStatisticMap);
        return R.ok(vo);
    }

    private Map<Long, List<TreeSelect>> getTypeTreeStatistic(Map<Long, List<FaultFullInfoExcel>> mDeptIdFaultMap, List<TreeSelect> typeTreeList) {
        Map<Long, List<TreeSelect>> resultMap = new HashMap<>();
        mDeptIdFaultMap.forEach((mDeptId,faults)->{
            List<TreeSelect> newTreeList = copyList(typeTreeList);
            getTypeFaultStatisticByFaultFullInfoVo(faults,newTreeList);
            resultMap.put(mDeptId,newTreeList);
        });
        return resultMap;
    }

    private List<TreeSelect> copyList(List<TreeSelect> typeTreeList){
       return  typeTreeList.stream().map(t -> {
            TreeSelect treeSelect = new TreeSelect();
            BeanUtils.copyProperties(t, treeSelect);
            if(t.getChildren()!=null&&t.getChildren().size()>0){
                treeSelect.setChildren(copyList(t.getChildren()));
            }
            return treeSelect;
        }).collect(Collectors.toList());
    }

    private void getTypeFaultStatisticByFaultFullInfoVo(List<FaultFullInfoExcel> faults, List<TreeSelect> typeTreeList){
        for (FaultFullInfoExcel faultAsset : faults) {
            String assetTypeAncestors = faultAsset.getAssetTypeAncestors();
            assetTypeAncestors = assetTypeAncestors + "," + faultAsset.getAssetTypeId();
            Long[] longs = Convert.toLongArray(assetTypeAncestors);

            for (Long typeId : longs) {
                treeNumberAdd(typeTreeList, typeId);
            }
        }
    }

    private void getTypeFaultStatistic(List<AsmsFaultAsset> faults, List<TreeSelect> typeTreeList){
//        Set<Long> topTypeIds = new HashSet<>();
//        Set<Long> hasTypeIds = new HashSet<>();
//        for (AsmsFaultAsset faultAsset : faults) {
//            if (faultAsset.getAssetTypeAncestors() != null) {
//                Long[] longs = Convert.toLongArray(faultAsset.getAssetTypeAncestors());
//                if (longs.length > 1) {
//                    topTypeIds.add(longs[1]);
//                    hasTypeIds.add(faultAsset.getAssetTypeId());
//                }
//            }
//        }
        //R<List<TreeSelect>> rTypeTreeList = remoteAssetTypeService.treeSelectByTypeIds(topTypeIds.toArray(new Long[0]));

//        Iterator<TreeSelect> iterator = typeTreeList.iterator();
//        while (iterator.hasNext()) {
//            if (findTreeSelectNext(iterator.next(), hasTypeIds)) {
//                iterator.remove();
//            }
//        }
        for (AsmsFaultAsset faultAsset : faults) {
            String assetTypeAncestors = faultAsset.getAssetTypeAncestors();
            assetTypeAncestors = assetTypeAncestors + "," + faultAsset.getAssetTypeId();
            Long[] longs = Convert.toLongArray(assetTypeAncestors);

            for (Long typeId : longs) {
                treeNumberAdd(typeTreeList, typeId);
            }
        }
    }

    private void treeNumberAdd(List<TreeSelect> typeTreeList, Long typeId) {
        for (TreeSelect treeSelect : typeTreeList) {

            if (treeSelect.getChildren() != null && treeSelect.getChildren().size() > 0) {
                treeNumberAdd(treeSelect.getChildren(), typeId);
            }
            if (treeSelect.getKey().equals(typeId)) {
                treeSelect.setAssetNum(treeSelect.getAssetNum() == null ? 1 : treeSelect.getAssetNum() + 1);
            }
        }
    }

    private Boolean findTreeSelectNext(TreeSelect tree, Set<Long> typeIds) {
        AtomicBoolean isNeedRemove = new AtomicBoolean(true);
        if (tree.getChildren() != null && tree.getChildren().size() > 0) {
            Iterator<TreeSelect> iterator = tree.getChildren().iterator();
            while (iterator.hasNext()) {
                if (findTreeSelectNext(iterator.next(), typeIds)) {
                    iterator.remove();
                } else {
                    isNeedRemove.set(false);
                }
            }
            //isNeedRemove.set(tree.getChildren().removeIf(treeSelect -> findTreeSelectNext(treeSelect, typeIds)));

        } else {
            if (typeIds.contains(tree.getKey())) {
                isNeedRemove.set(false);
            }
        }
        return isNeedRemove.get();
    }

    /**
     * 根据资产类型分故障类型数量统计
     */
    @GetMapping("/getFaultNumberByType/{assetTypeId}")
    public AjaxResult getFaultNumberByFaultType(@PathVariable("assetTypeId") Long assetTypeId) {

        Long deptId = SecurityUtils.getDeptId();
        /** Long deptId = 27l; */

        return AjaxResult.success(asmsFaultAssetService.getFaultNumber(null, deptId, assetTypeId));
    }

    /**
     * 分部门维修人员处理情况
     */
    @GetMapping("/getRepairResultByDept")
    public AjaxResult getRepairResultByDept() {
        Set<Long> userMaintenanceDeptIds = null;
        if (SecurityUtils.getUserId() == 1) {
            userMaintenanceDeptIds = new HashSet<>();
            userMaintenanceDeptIds.add(-2l);
        } else {
            userMaintenanceDeptIds = tokenService.getUserMaintenanceDeptIds();
        }
        if (userMaintenanceDeptIds == null || userMaintenanceDeptIds.size() < 1) {
            return AjaxResult.error("未找到该用户的维护部门信息");
        }

        List<TreeSelect> datas =deptController.rTreeselects(userMaintenanceDeptIds).getData();
        if (datas == null || datas.size() < 1) {
            return AjaxResult.error("部门信息获取失败,由于不存在该部门信息或系统服务掉线");
        }
        List<AssetRepairNumberVo> list = new LinkedList<>();
        for (TreeSelect tree : datas) {
            AssetRepairNumberVo repairResultByDept = asmsAssetFullInfoService.getRepairResultByDept(tree);
            list.add(repairResultByDept);
            System.out.println(repairResultByDept);
        }

        return AjaxResult.success(list);
    }

    /**
     * 根据部门分故障类型数量统计
     */
    @GetMapping("/getFaultNumberByDept/{deptId}")
    public AjaxResult getFaultNumberByFaultDept(@PathVariable("deptId") Long deptId) {

        return AjaxResult.success(asmsFaultAssetService.getFaultNumber(deptId, null, null));
    }

    @PreAuthorize
    @ApiOperation("查看故障处理进度")
    @GetMapping("/getFaultFullInfo")
    public TableDataInfo getFaultFullInfo(GetFaultFullInfoSearchVo vo) {
//        Long start = System.currentTimeMillis();

        //构造一个包含所有故障信息的列表
        List<FaultAssetFullInfoVo> vos = new ArrayList<>();
        //先查询出当前部门类型对应的所有的故障信息
        QueryWrapper<FaultInfoView> wrapper = new QueryWrapper<>();

        //系统管理员查看所有故障、其他用户查看自己可以看见的部门的相关故障信息
        // .or().in(FaultInfoView.OWN_DEPT_ID, userCanLookDeptIds)
        Set<Long> userCanLookDeptIds = tokenService.getUserCanLookDeptIds();
        if (!SysUser.isAdmin(SecurityUtils.getUserId()) && userCanLookDeptIds != null
                && userCanLookDeptIds.size() > 0) {
            wrapper.in(FaultInfoView.MAINTENANCE_DEPT_ID, userCanLookDeptIds);
        }
        //查询条件
        if (vo.getOwnDeptId() != null)
            wrapper.eq(FaultInfoView.OWN_DEPT_ID, vo.getOwnDeptId());

        if (vo.getMaintenanceDeptId() != null)
            wrapper.eq(FaultInfoView.MAINTENANCE_DEPT_ID, vo.getMaintenanceDeptId());

        if (vo.getIsFinish() != null)
            wrapper.eq(FaultInfoView.IS_FINISH, vo.getIsFinish());

        if (vo.getStage() != null)
            wrapper.eq(FaultInfoView.STAGE, vo.getStage());

        if (vo.getFaultResolveUserId() != null)
            wrapper.eq(FaultInfoView.FAULT_RESOLVE_USER_ID, vo.getFaultResolveUserId());

        if (vo.getFaultAssetId() != null)
            wrapper.eq(FaultInfoView.FAULT_ASSET_ID, vo.getFaultAssetId());

        if (StringUtils.isNotEmpty(vo.getAssetTypeName())) {
            R<HashSet<Long>> assetTypeByName = assetTypeController.getAssetTypeByName(vo.getAssetTypeName());
            if (assetTypeByName.getCode() == R.FAIL)
                return asmsReusingService.resovleError();
            HashSet<Long> typeIds = assetTypeByName.getData();
            if (typeIds.size() == 0)
                return getDataTable(vos);
            wrapper.in(FaultInfoView.ASSET_TYPE_ID, typeIds);
        }

        wrapper.orderByDesc(FaultInfoView.CREATE_TIME);
        //获取故障视图表中的故障
        startPage();
        List<FaultInfoView> faultInfoView = faultInfoViewService.list(wrapper);
        //构建一个资产ID的集合
        HashSet<Long> assetIds = new HashSet<>();
        HashSet<Long> faultAssetIds = new HashSet<>();
        HashSet<Long> userIds = new HashSet<>();
        HashSet<Long> deptIds = new HashSet<>();
        for (FaultInfoView infoView : faultInfoView) {
            if(infoView.getFaultFindUserId()!=null)
            userIds.add(infoView.getFaultFindUserId());
            if (infoView.getFaultResolveUserId()!=null)
            userIds.add(infoView.getFaultResolveUserId());
            if (infoView.getMaintenanceDeptId()!=null)
            deptIds.add(infoView.getMaintenanceDeptId());
            if (infoView.getOwnDeptId()!=null)
            deptIds.add(infoView.getOwnDeptId());
            assetIds.add(infoView.getAssetId());
            faultAssetIds.add(infoView.getFaultAssetId());
        }

        //将故障的资产、报修、派单、处理、确认阶段的所有数据封装到Map中
        HashMap<Long, AsmsAssetFullInfo> assetFullInfoMap = new HashMap<>();
        HashMap<Long, AsmsFaultReportStage> reportMap = new HashMap<>();
        HashMap<Long, AsmsFaultDispatchStage> dispatchMap = new HashMap<>();
        HashMap<Long, AsmsFaultResolveStage> resolveMap = new HashMap<>();
        HashMap<Long, AsmsFaultConfirmStage> confirmMap = new HashMap<>();
        Map<Long, SysUser> allUserMap = new HashMap<>();
        Map<Long, SysDept> allDeptMap = new HashMap<>();
        //获取系统所有用户的Map
//        long asyncTimeStart =System.currentTimeMillis();
//        System.out.println("异步前调用累计用时:"+(asyncTimeStart-start)/1000 +"秒");
        CompletableFuture<R<Map<Long, SysUser>>> userFuture = CompletableFuture.supplyAsync(() ->userController
                .getUserListByIds(userIds.toArray(new Long[0])));

        //获取系统所有部门的Map
        CompletableFuture<R<Map<Long, SysDept>>> deptFuture = CompletableFuture.supplyAsync(() ->
                deptController.getDeptMapByIds(deptIds));
        //异步查询，提高速度
        CompletableFuture<List<AsmsAssetFullInfo>> assetFullInfoList = CompletableFuture.supplyAsync(() ->
                asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                        .in(assetIds.size() > 0, AsmsAssetFullInfo.ASSET_ID, assetIds))
        );

        CompletableFuture<List<AsmsFaultReportStage>> reportStageList = CompletableFuture.supplyAsync(() ->
                asmsFaultReportStageService.list(new QueryWrapper<AsmsFaultReportStage>()
                        .in(faultAssetIds.size() > 0, AsmsFaultReportStage.FAULT_ASSET_ID, faultAssetIds))
        );

        CompletableFuture<List<AsmsFaultDispatchStage>> dispatchStageList = CompletableFuture.supplyAsync(() ->
                asmsFaultDispatchStageService.list(new QueryWrapper<AsmsFaultDispatchStage>()
                        .in(faultAssetIds.size() > 0, AsmsFaultDispatchStage.FAULT_ASSET_ID, faultAssetIds))
        );

        CompletableFuture<List<AsmsFaultResolveStage>> resolveStageList = CompletableFuture.supplyAsync(() ->
                asmsFaultResolveStageService.list(new QueryWrapper<AsmsFaultResolveStage>()
                        .in(faultAssetIds.size() > 0, AsmsFaultResolveStage.FAULT_ASSET_ID, faultAssetIds)
                        .ne(AsmsFaultResolveStage.STATUS, -2))
        );

        CompletableFuture<List<AsmsFaultConfirmStage>> confirmStageList = CompletableFuture.supplyAsync(() ->
                asmsFaultConfirmStageService.list(new QueryWrapper<AsmsFaultConfirmStage>()
                        .in(faultAssetIds.size() > 0, AsmsFaultConfirmStage.FAULT_ASSET_ID, faultAssetIds))
        );

        try {
            HashSet<Long> antherUserIds = new HashSet<>();
            assetFullInfoList.get().forEach(item -> {
                assetFullInfoMap.put(item.getAssetId(), item);
            });
            reportStageList.get().forEach(item -> {
                reportMap.put(item.getFaultAssetId(), item);
                if (item.getOwnChargeUserId()!=null)
                antherUserIds.add(item.getOwnChargeUserId());
            });
            dispatchStageList.get().forEach(item -> {
                dispatchMap.put(item.getFaultAssetId(), item);
                if (item.getMaintenanceChargeUserId()!=null)
                antherUserIds.add(item.getMaintenanceChargeUserId());
            });
            CompletableFuture<R<Map<Long, SysUser>>> antherUserFuture = CompletableFuture.supplyAsync(() ->
                    userController.getUserListByIds(antherUserIds.toArray(new Long[0])));

            resolveStageList.get().forEach(item -> resolveMap.put(item.getFaultAssetId(), item));
            confirmStageList.get().forEach(item -> confirmMap.put(item.getFaultAssetId(), item));

            if (userFuture.get().getCode() == R.FAIL||antherUserFuture.get().getCode() == R.FAIL)
                return asmsReusingService.resovleError();
            allUserMap = userFuture.get().getData();
            allUserMap.putAll(antherUserFuture.get().getData());

            if (deptFuture.get().getCode() == R.FAIL)
                return asmsReusingService.resovleError();
            allDeptMap = deptFuture.get().getData();

        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        /*long asyncTimeEnd =System.currentTimeMillis();
        System.out.println("异步调用累计用时:"+(asyncTimeEnd-asyncTimeStart)/1000 +"秒");*/
        for (FaultInfoView view : faultInfoView) {
            //构建一个存放故障资产信息的vo
            FaultAssetFullInfoVo infoVo = new FaultAssetFullInfoVo();

            FaultUserAddressAssetInfo faultUserAddressAssetInfo = new FaultUserAddressAssetInfo();
            BeanUtils.copyProperties(view, faultUserAddressAssetInfo);
            AsmsAssetFullInfo fullInfo = assetFullInfoMap.get(view.getAssetId());
            if (fullInfo != null) {
                BeanUtils.copyProperties(fullInfo, faultUserAddressAssetInfo);
                faultUserAddressAssetInfo.setFullName(fullInfo.getAddressFullName());
            }
            faultUserAddressAssetInfo.setUserId(view.getFaultFindUserId());
            SysUser finder = allUserMap.get(view.getFaultFindUserId());
            if (finder != null) {
                faultUserAddressAssetInfo.setNickName(finder.getNickName());
                faultUserAddressAssetInfo.setPhonenumber(finder.getPhonenumber());
            }
            faultUserAddressAssetInfo.setCreateTime(view.getCreateTime());
            infoVo.setBasicInfo(faultUserAddressAssetInfo);

            if (view.getStage() >= 1) {
                ReportStageInfoVo reportStageInfoVo = new ReportStageInfoVo();
                AsmsFaultReportStage reportStage = reportMap.get(view.getFaultAssetId());
                if (reportStage != null) {
                    BeanUtils.copyProperties(reportStage, reportStageInfoVo);
                    SysUser sysUser = allUserMap.get(reportStage.getOwnChargeUserId());
                    if (sysUser != null) {
                        reportStageInfoVo.setOwnChargeUserName(sysUser.getNickName());
                        reportStageInfoVo.setOwnChargeUserPhone(sysUser.getPhonenumber());
                    }
                }
                if (view.getOwnDeptId() != null) {
                    reportStageInfoVo.setOwnChargeDeptId(view.getOwnDeptId());
                }
                SysDept sysDept = allDeptMap.get(view.getOwnDeptId());
                if (sysDept != null) {
                    reportStageInfoVo.setOwnChargeDeptName(sysDept.getDeptFullName());
                }
                infoVo.setReportStage(reportStageInfoVo);
            }
            if (view.getStage() >= 2) {
                DispatchStageInfoVo dispatchStageInfoVo = new DispatchStageInfoVo();
                AsmsFaultDispatchStage dispatchStage = dispatchMap.get(view.getFaultAssetId());
                if (dispatchStage != null) {
                    BeanUtils.copyProperties(dispatchStage, dispatchStageInfoVo);
                    SysDept sysDept = allDeptMap.get(dispatchStage.getMaintenanceDeptId());
                    if (sysDept != null) {
                        dispatchStageInfoVo.setMaintenanceDeptName(sysDept.getDeptFullName());
                    }
                    SysUser sysUser = allUserMap.get(dispatchStage.getMaintenanceChargeUserId());
                    if (sysUser != null) {
                        dispatchStageInfoVo.setMaintenanceChargeUserName(sysUser.getNickName());
                        dispatchStageInfoVo.setMaintenanceChargeUserPhone(sysUser.getPhonenumber());
                    }
                }
                infoVo.setDispatchStage(dispatchStageInfoVo);
            }
            if (view.getStage() >= 3) {
                ResolveStageInfoVo resolveStageInfoVo = new ResolveStageInfoVo();
                AsmsFaultResolveStage resolveStage = resolveMap.get(view.getFaultAssetId());
                if (resolveStage != null) {
                    BeanUtils.copyProperties(resolveStage, resolveStageInfoVo);
                    SysUser user = allUserMap.get(resolveStage.getFaultResolveUserId());
                    if (user != null) {
                        resolveStageInfoVo.setFaultResolveUserName(user.getNickName());
                        resolveStageInfoVo.setFaultResolveUserPhone(user.getPhonenumber());
                    }
                }
                infoVo.setResolveStage(resolveStageInfoVo);
            }
            if (view.getStage() >= 4) {
                ConfirmStageInfoVo confirmStageInfoVo = new ConfirmStageInfoVo();
                AsmsFaultConfirmStage confirmStage = confirmMap.get(view.getFaultAssetId());
                if (confirmStage != null) {
                    BeanUtils.copyProperties(confirmStage, confirmStageInfoVo);
                }
                infoVo.setConfirmStage(confirmStageInfoVo);
            }
            //向故障信息列表中加入故障信息
            vos.add(infoVo);
        }
        TableDataInfo dataTable = getDataTable(faultInfoView);
        dataTable.setData(vos);
//        long end = System.currentTimeMillis();
//        System.out.println("异步后调用累计用时:"+(end-asyncTimeEnd)/1000 +"秒");
//        System.out.println("接口累计用时:"+(start-end)/1000 +"秒");
        return dataTable;
    }

    @PreAuthorize
    @ApiOperation("故障派单阶段退回故障")
    @GetMapping("/refund")
    public AjaxResult refund(@ApiParam(value = "资产故障ID，从返回的list中的dispatchStage中获取", required = true) Long faultAssetId) {
        Set<String> roles = tokenService.getLoginUser().getRoles();
        boolean flag = false;
        for (String role : roles) {
            if (role.contains("管理员") || role.contains("负责人")
                    || role.contains("决策者")) {
                flag = true;
            }
        }
        if (!flag) {
            return AjaxResult.error("您没有退回故障的权限！");
        }
        asmsFaultDispatchStageService.update(new UpdateWrapper<AsmsFaultDispatchStage>()
                .set(AsmsFaultDispatchStage.STATUS, -1)
                .eq(AsmsFaultDispatchStage.FAULT_ASSET_ID, faultAssetId));
        return AjaxResult.success("退回成功！");
    }

    @PreAuthorize
    @ApiOperation("导出故障信息")
    @PostMapping(value="/exportFaultInfo", produces = "application/octet-stream")
    public AjaxResult exportFaultInfo(HttpServletResponse response, GetFaultFullInfoSearchVo vo) throws IOException {
        TableDataInfo dataInfo = getFaultFullInfo(vo);
        List<FaultAssetFullInfoVo> data = (List<FaultAssetFullInfoVo>) dataInfo.getData();
        //开始导出数据
        List<ExportFaultVo> result = new ArrayList<>();
        for (FaultAssetFullInfoVo infoVo : data) {
            ExportFaultVo exportFaultVo = new ExportFaultVo();
            FaultUserAddressAssetInfo basicInfo = infoVo.getBasicInfo();
            ReportStageInfoVo reportStage = infoVo.getReportStage();
            DispatchStageInfoVo dispatchStage = infoVo.getDispatchStage();
            ResolveStageInfoVo resolveStage = infoVo.getResolveStage();
            ConfirmStageInfoVo confirmStage = infoVo.getConfirmStage();
            if (basicInfo != null)
                BeanUtils.copyProperties(basicInfo, exportFaultVo);

            if (reportStage != null)
                BeanUtils.copyProperties(reportStage, exportFaultVo);

            if (dispatchStage != null)
                BeanUtils.copyProperties(dispatchStage, exportFaultVo);

            if (resolveStage != null)
                BeanUtils.copyProperties(resolveStage, exportFaultVo);

            if (confirmStage != null)
                BeanUtils.copyProperties(confirmStage, exportFaultVo);

            result.add(exportFaultVo);
        }
        ExcelUtil<ExportFaultVo> util = new ExcelUtil<>(ExportFaultVo.class);
        util.exportExcel(response, result, "故障信息表");
        return AjaxResult.success("导出成功");
    }

    private void removeAsmsFaultAssets(List<AsmsFaultAsset> lists) {
        List<Long> faultAssetIds = lists.stream().map(AsmsFaultAsset::getFaultAssetId).collect(Collectors.toList());
        List<Long> faultIds =lists.stream().map(AsmsFaultAsset::getFaultId).collect(Collectors.toList());

        asmsFaultService.removeByIds(faultIds);
        asmsFaultAssetService.removeByIds(faultAssetIds);
        asmsFaultConfirmStageService.remove(new QueryWrapper<AsmsFaultConfirmStage>()
                .in(AsmsFaultConfirmStage.FAULT_ASSET_ID,faultAssetIds));

        asmsFaultReportStageService.remove(new QueryWrapper<AsmsFaultReportStage>()
                .in(AsmsFaultReportStage.FAULT_ASSET_ID,faultAssetIds));

        asmsFaultDispatchStageService.remove(new QueryWrapper<AsmsFaultDispatchStage>()
                .in(AsmsFaultDispatchStage.FAULT_ASSET_ID,faultAssetIds));

        asmsFaultResolveStageService.remove(new QueryWrapper<AsmsFaultResolveStage>()
                .in(AsmsFaultResolveStage.FAULT_ASSET_ID,faultAssetIds));
    }

    @GetMapping("/deleteFaultData")
    public void deleteErrorFaultData(Long start, Long end) {
        List<AsmsFaultAsset> faultAssets = asmsFaultAssetService.list(new QueryWrapper<AsmsFaultAsset>()
                .ge(AsmsFaultAsset.FAULT_ASSET_ID, start).le(AsmsFaultAsset.FAULT_ASSET_ID, end));
        removeAsmsFaultAssets(faultAssets);
    }

    @GetMapping("/deleteFaultDescription")
    public void deleteFaultDescription(String[] descriptions){
        List<AsmsFaultAsset> faultAssets = asmsFaultAssetService
                .list(new QueryWrapper<AsmsFaultAsset>().in(AsmsFaultAsset.DESCRIPTION,descriptions));
        removeAsmsFaultAssets(faultAssets);
    }

    /**
     * 获取每个维修人员剩余待处理工单的数量
     * @return
     */
    @PostMapping("/getRepairersWorkNum")
    public R<Map<Long, Integer>> getRepairersWorkNum(@RequestBody Set<Long> userIds) {
        Map<Long, Integer> result = new HashMap<>();
        if (userIds.size() == 0) return R.ok(result);

        //查询维修人员还没维修完的故障
        List<AsmsFaultAsset> list = asmsFaultAssetService.list(new QueryWrapper<AsmsFaultAsset>()
                .select(AsmsFaultAsset.FAULT_ASSET_ID, AsmsFaultAsset.FAULT_RESOLVE_USER_ID)
                .in(AsmsFaultAsset.FAULT_RESOLVE_USER_ID, userIds).eq(AsmsFaultAsset.STAGE, 3)
        );
        for (Long userId : userIds) {
            Integer workNum = 0;
            for (AsmsFaultAsset faultAsset : list) {
                if (userId.equals(faultAsset.getFaultResolveUserId()))
                    workNum ++;
            }
            result.put(userId, workNum);
        }
        return R.ok(result);
    }

    @ApiOperation("获取工单池列表")
    @GetMapping("/getWorkOrderPool")
    public AjaxResult getWorkOrderPool() {
        List<WorkOrderPoolVo> result = new ArrayList<>();
        //先获取当前可见的维护部门
        Set<Long> deptIds = tokenService.getUserMaintenanceDeptIds();

        if (deptIds.size() == 0) return AjaxResult.success(result);

        QueryWrapper<FaultInfoView> wrapper = new QueryWrapper<>();
        //排除已撤销的故障
        Set<Long> hasCancelFaults = asmsReusingService.getHasCancelFaults();
        if (hasCancelFaults.size() > 0) {
            wrapper.notIn(FaultInfoView.FAULT_ASSET_ID, hasCancelFaults);
        }

        //获取维护的学校所报过来的故障
        List<FaultInfoView> faultInfoViews = faultInfoViewService.list(wrapper
                .select(FaultInfoView.FAULT_ASSET_ID, FaultInfoView.ASSET_TYPE_ID, FaultInfoView.FAULT_FIND_USER_ID,
                        FaultInfoView.ADDRESS_ID, FaultInfoView.CREATE_TIME, FaultInfoView.DESCRIPTION,
                        FaultInfoView.DESCRIPTION_IMAGES, FaultInfoView.OWN_DEPT_ID)
                .eq(FaultInfoView.STAGE, 2).in(FaultInfoView.MAINTENANCE_DEPT_ID, deptIds)
        );

        if (faultInfoViews.size() == 0) return AjaxResult.success(result);

        //异步查询数据
        Set<Long> faultAssetIds = faultInfoViews.stream().map(FaultInfoView::getFaultAssetId).collect(Collectors.toSet());
        Set<Long> assetTypeIds = faultInfoViews.stream().map(FaultInfoView::getAssetTypeId).collect(Collectors.toSet());
        Set<Long> finderIds = faultInfoViews.stream().map(FaultInfoView::getFaultFindUserId).collect(Collectors.toSet());
        Set<Long> addressIds = faultInfoViews.stream().map(FaultInfoView::getAddressId).collect(Collectors.toSet());
        Set<Long> ownDepIds = faultInfoViews.stream().map(FaultInfoView::getOwnDeptId).collect(Collectors.toSet());

        CompletableFuture<List<AsmsFaultReportStage>> f1 = CompletableFuture.supplyAsync(() ->
                asmsFaultReportStageService.list(new QueryWrapper<AsmsFaultReportStage>()
                        .select(AsmsFaultReportStage.FAULT_ASSET_ID, AsmsFaultReportStage.URGENCY_DEGREE)
                        .in(AsmsFaultReportStage.FAULT_ASSET_ID, faultAssetIds))
        );
        CompletableFuture<R<Map<Long, AmsAssetType>>> f2 = CompletableFuture.supplyAsync(() ->
                assetTypeController.getAddressByIds(assetTypeIds.toArray(new Long[0]))
        );
        CompletableFuture<R<Map<Long, SysUser>>> f3 = CompletableFuture.supplyAsync(() ->
                userController.getUserListByIds(finderIds.toArray(new Long[0]))
        );
        CompletableFuture<R<Map<Long, AmsOwnAddress>>> f4 = CompletableFuture.supplyAsync(() ->
                ownAddressController.getAddressByIds(addressIds.toArray(new Long[0]))
        );
        CompletableFuture<R<List<SysDept>>> f5 = CompletableFuture.supplyAsync(() ->
                deptController.getDeptListByIds(Sets.newHashSet(ownDepIds))
        );

        Map<Long, Integer> reportMap = new HashMap<>();
        Map<Long, AmsAssetType> assetTypeMap = new HashMap<>();
        Map<Long, SysUser> userMap = new HashMap<>();
        Map<Long, AmsOwnAddress> addressMap = new HashMap<>();
        Map<Long, String> deptMap = new HashMap<>();
        try {
            List<AsmsFaultReportStage> reportStages = f1.get();
            R<Map<Long, AmsAssetType>> assetTypeR = f2.get();
            R<Map<Long, SysUser>> userR = f3.get();
            R<Map<Long, AmsOwnAddress>> addressR = f4.get();
            R<List<SysDept>> deptR = f5.get();

            if (assetTypeR.getCode() == R.FAIL) throw new ServiceException(assetTypeR.getMsg());
            if (userR.getCode() == R.FAIL) throw new ServiceException(userR.getMsg());
            if (addressR.getCode() == R.FAIL) throw new ServiceException(addressR.getMsg());
            if (deptR.getCode() == R.FAIL) throw new ServiceException(deptR.getMsg());

            assetTypeMap = assetTypeR.getData();
            userMap = userR.getData();
            addressMap = addressR.getData();
            if (reportStages != null) {
                reportMap = reportStages.stream().collect(Collectors
                        .toMap(AsmsFaultReportStage::getFaultAssetId, AsmsFaultReportStage::getUrgencyDegree));
            }
            if (deptR.getData() != null) {
                deptMap = deptR.getData().stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptFullName));
            }

        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        for (FaultInfoView view : faultInfoViews) {
            WorkOrderPoolVo vo = new WorkOrderPoolVo();
            BeanUtils.copyProperties(view, vo);

            //故障资产名称
            AmsAssetType type = assetTypeMap.get(view.getAssetTypeId());
            vo.setFaultAssetName(type != null ? type.getAssetTypeName() : "未知");

            //报修人员信息
            SysUser user = userMap.get(view.getFaultFindUserId());
            vo.setFinderName(user != null ? user.getNickName() : "未知");
            vo.setFinderTel(user != null ? user.getPhonenumber() : "未知");

            //报修时间字符串
            vo.setTimeStr(asmsReusingService.getPastTimeLength(view.getCreateTime()));

            //报修地点
            AmsOwnAddress address = addressMap.get(view.getAddressId());
            vo.setFindFaultAddress(address != null ? address.getFullName() : "未知");

            //故障资产所属方名称
            String deptName = deptMap.get(view.getOwnDeptId());
            vo.setOwnDeptName(deptName != null ? deptName : "未知");

            //紧急程度
            Integer urgencyDegree = reportMap.get(view.getFaultAssetId());
            vo.setUrgencyDegree(urgencyDegree != null ? urgencyDegree : 1);

            result.add(vo);
        }
        //按报修时间降序
        result.sort(Comparator.comparing(WorkOrderPoolVo::getCreateTime).reversed());
        return AjaxResult.success(result);
    }

    @ApiOperation("工单池抢单")
    @PostMapping("/robWorkOrder")
    public AjaxResult robWorkOrder(@RequestBody WorkOrderDto dto) {
        //判断预计维修时间是否有效
        if (dto.getEstimateFixTime() < System.currentTimeMillis()) {
            return AjaxResult.error("预计维修时间无效");
        }
        //完善派单阶段信息
        asmsFaultDispatchStageService.update(new UpdateWrapper<AsmsFaultDispatchStage>()
                .set(AsmsFaultDispatchStage.END_TIME, System.currentTimeMillis())
                .set(AsmsFaultDispatchStage.MAINTENANCE_CHARGE_USER_ID, SecurityUtils.getUserId())
                .set(AsmsFaultDispatchStage.STATUS, 1)
                .set(AsmsFaultDispatchStage.IS_ACTIVE_RECEIVE, 0)
                .eq(AsmsFaultDispatchStage.FAULT_ASSET_ID, dto.getFaultAssetId())
        );
        //修改故障阶段
        asmsFaultAssetService.update(new UpdateWrapper<AsmsFaultAsset>()
                .set(AsmsFaultAsset.STAGE, 3).set(AsmsFaultAsset.FAULT_RESOLVE_USER_ID, SecurityUtils.getUserId())
                .eq(AsmsFaultAsset.FAULT_ASSET_ID, dto.getFaultAssetId())
        );
        //开启故障处理阶段
        AsmsFaultResolveStage resolveStage = new AsmsFaultResolveStage();
        resolveStage.setFaultAssetId(dto.getFaultAssetId()).setStartTime(System.currentTimeMillis())
                .setEstimateFixTime(dto.getEstimateFixTime()).setFaultResolveUserId(SecurityUtils.getUserId())
                .setMaintenanceDeptId(SecurityUtils.getDeptId()).setStatus(0);
        asmsFaultResolveStageService.save(resolveStage);

        return AjaxResult.success();
    }

}
